#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import jieba
from flask import current_app
from pymongo import TEXT
from pymongo.errors import PyMongoError
from app.database import get_database

class CivilCodeServiceImproved:
    def __init__(self):
        """初始化服务"""
        self.db = None
        self.collection = None
        self.favorites_collection = None
        self.history_collection = None
        self._initialized = False
    
    def _init_db(self):
        """延迟初始化数据库连接"""
        if not self._initialized:
            try:
                self.db = get_database()
                self.collection = self.db.articles if self.db is not None else None
                self.favorites_collection = self.db.user_favorites if self.db is not None else None
                self.history_collection = self.db.search_history if self.db is not None else None
                if self.collection is not None:
                    self._ensure_indexes()
                self._initialized = True
            except Exception as e:
                current_app.logger.error(f"数据库初始化失败: {e}")
                self._initialized = False

    def _ensure_indexes(self):
        """确保所有必要的索引存在"""
        try:
            # 全文搜索索引
            if "full_text_search" not in self.collection.index_information():
                self.collection.create_index([
                    ("content", TEXT),
                    ("title", TEXT)
                ], name="full_text_search", default_language='none')
                current_app.logger.info("创建全文搜索索引 full_text_search")

            # 关键词数组索引
            if "keywords_index" not in self.collection.index_information():
                self.collection.create_index([("keywords", 1)], name="keywords_index")
                current_app.logger.info("创建关键词索引 keywords_index")

            # 条文号唯一索引
            if "article_number_unique" not in self.collection.index_information():
                self.collection.create_index([("article_number", 1)], unique=True, name="article_number_unique")
                current_app.logger.info("创建条文号唯一索引 article_number_unique")

            # 章节复合索引
            if "part_chapter_index" not in self.collection.index_information():
                self.collection.create_index([
                    ("part", 1),
                    ("chapter", 1)
                ], name="part_chapter_index")
                current_app.logger.info("创建章节复合索引 part_chapter_index")

            current_app.logger.info("所有索引已确保存在")

        except PyMongoError as e:
            current_app.logger.error(f"创建索引失败: {e}")

    def smart_search(self, query: str, page: int = 1, per_page: int = 20):
        """智能组合搜索法条 - 改进版"""
        self._init_db()
        if self.collection is None:
            return {"articles": [], "pagination": {}, "search_info": {"query": query, "result_count": 0, "strategy": "db_not_connected"}}

        # 预处理查询词
        seg_list = jieba.lcut_for_search(query)
        seg_list = [word for word in seg_list if len(word) > 1 and word not in ['的', '了', '在', '是', '和', '与', '或']]
        
        current_app.logger.debug(f"搜索查询: '{query}', 分词结果: {seg_list}")

        # 1. 尝试全文搜索 (最高权重)
        text_search_results = []
        try:
            text_search_results = list(self.collection.find(
                {"$text": {"$search": query}},
                {"score": {"$meta": "textScore"}}
            ).sort([("score", {"$meta": "textScore"})]).limit(per_page * 3))
            current_app.logger.debug(f"全文搜索找到 {len(text_search_results)} 条结果")
        except PyMongoError as e:
            current_app.logger.warning(f"全文搜索失败: {e}")

        # 2. 多关键词内容匹配搜索 (高权重)
        multi_keyword_results = []
        try:
            # 构建多关键词查询 - 要求包含多个关键词
            if len(seg_list) >= 2:
                multi_conditions = []
                for word in seg_list:
                    multi_conditions.append({"content": {"$regex": word, "$options": "i"}})
                
                multi_keyword_query = {"$and": multi_conditions}
                multi_keyword_results = list(self.collection.find(multi_keyword_query).limit(per_page * 2))
                current_app.logger.debug(f"多关键词内容搜索找到 {len(multi_keyword_results)} 条结果")
        except PyMongoError as e:
            current_app.logger.warning(f"多关键词搜索失败: {e}")

        # 3. 单关键词内容匹配搜索 (中等权重)
        single_keyword_results = []
        try:
            # 对每个关键词进行内容搜索
            single_conditions = []
            for word in seg_list:
                single_conditions.append({"content": {"$regex": word, "$options": "i"}})
            
            if single_conditions:
                single_keyword_query = {"$or": single_conditions}
                single_keyword_results = list(self.collection.find(single_keyword_query).limit(per_page * 3))
                current_app.logger.debug(f"单关键词内容搜索找到 {len(single_keyword_results)} 条结果")
        except PyMongoError as e:
            current_app.logger.warning(f"单关键词搜索失败: {e}")

        # 4. 关键词数组搜索 (低权重，仅作补充)
        keyword_array_results = []
        try:
            keyword_query = {"keywords": {"$in": seg_list}}
            keyword_array_results = list(self.collection.find(keyword_query).limit(per_page))
            current_app.logger.debug(f"关键词数组搜索找到 {len(keyword_array_results)} 条结果")
        except PyMongoError as e:
            current_app.logger.warning(f"关键词数组搜索失败: {e}")

        # 5. 标题匹配搜索 (高权重)
        title_search_results = []
        try:
            title_conditions = []
            for word in seg_list:
                title_conditions.append({"title": {"$regex": word, "$options": "i"}})
            
            if title_conditions:
                title_query = {"$or": title_conditions}
                title_search_results = list(self.collection.find(title_query).limit(per_page))
                current_app.logger.debug(f"标题搜索找到 {len(title_search_results)} 条结果")
        except PyMongoError as e:
            current_app.logger.warning(f"标题搜索失败: {e}")

        # 合并并计算相关性分数
        combined_results_map = {}
        
        # 全文搜索结果 (权重: 10)
        for article in text_search_results:
            article_id = article['_id']
            score = article.get('score', 1) * 10
            combined_results_map[article_id] = {
                "article": article, 
                "score": score, 
                "strategies": ["text"],
                "match_details": {"text_score": article.get('score', 1)}
            }

        # 多关键词内容匹配 (权重: 8)
        for article in multi_keyword_results:
            article_id = article['_id']
            # 计算匹配的关键词数量
            content = article.get('content', '').lower()
            matched_keywords = [word for word in seg_list if word.lower() in content]
            match_score = len(matched_keywords) * 8
            
            if article_id not in combined_results_map:
                combined_results_map[article_id] = {
                    "article": article, 
                    "score": match_score, 
                    "strategies": ["multi_keyword"],
                    "match_details": {"matched_keywords": matched_keywords}
                }
            else:
                combined_results_map[article_id]["score"] += match_score
                combined_results_map[article_id]["strategies"].append("multi_keyword")
                combined_results_map[article_id]["match_details"]["matched_keywords"] = matched_keywords

        # 标题匹配 (权重: 6)
        for article in title_search_results:
            article_id = article['_id']
            title = article.get('title', '').lower()
            matched_in_title = [word for word in seg_list if word.lower() in title]
            title_score = len(matched_in_title) * 6
            
            if article_id not in combined_results_map:
                combined_results_map[article_id] = {
                    "article": article, 
                    "score": title_score, 
                    "strategies": ["title"],
                    "match_details": {"title_matches": matched_in_title}
                }
            else:
                combined_results_map[article_id]["score"] += title_score
                combined_results_map[article_id]["strategies"].append("title")
                combined_results_map[article_id]["match_details"]["title_matches"] = matched_in_title

        # 单关键词内容匹配 (权重: 3)
        for article in single_keyword_results:
            article_id = article['_id']
            content = article.get('content', '').lower()
            matched_keywords = [word for word in seg_list if word.lower() in content]
            single_score = len(matched_keywords) * 3
            
            if article_id not in combined_results_map:
                combined_results_map[article_id] = {
                    "article": article, 
                    "score": single_score, 
                    "strategies": ["single_keyword"],
                    "match_details": {"single_matches": matched_keywords}
                }
            else:
                combined_results_map[article_id]["score"] += single_score
                if "single_keyword" not in combined_results_map[article_id]["strategies"]:
                    combined_results_map[article_id]["strategies"].append("single_keyword")

        # 关键词数组匹配 (权重: 1，仅作补充)
        for article in keyword_array_results:
            article_id = article['_id']
            keywords = article.get('keywords', [])
            matched_array_keywords = [kw for kw in keywords if kw in seg_list]
            array_score = len(matched_array_keywords) * 1
            
            if article_id not in combined_results_map:
                combined_results_map[article_id] = {
                    "article": article, 
                    "score": array_score, 
                    "strategies": ["keyword_array"],
                    "match_details": {"array_matches": matched_array_keywords}
                }
            else:
                combined_results_map[article_id]["score"] += array_score
                if "keyword_array" not in combined_results_map[article_id]["strategies"]:
                    combined_results_map[article_id]["strategies"].append("keyword_array")

        # 按相关性分数排序
        sorted_results = sorted(combined_results_map.values(), key=lambda x: x["score"], reverse=True)
        
        # 分页处理
        total_results = len(sorted_results)
        start_index = (page - 1) * per_page
        end_index = start_index + per_page
        paginated_results = sorted_results[start_index:end_index]
        
        # 构建返回结果
        articles = []
        for result_data in paginated_results:
            article = result_data["article"]
            # 移除MongoDB的score字段，避免JSON序列化问题
            if 'score' in article:
                del article['score']
            # 转换_id为字符串
            if '_id' in article:
                article['_id'] = str(article['_id'])
            articles.append(article)

        # 分页信息
        pagination = {
            "page": page,
            "per_page": per_page,
            "total": total_results,
            "pages": (total_results + per_page - 1) // per_page
        }

        # 搜索信息
        strategy = "comprehensive_improved"
        if total_results == 0:
            strategy = "no_results"
        elif len(text_search_results) > 0:
            strategy = "text_primary"
        elif len(multi_keyword_results) > 0:
            strategy = "multi_keyword_primary"
        else:
            strategy = "keyword_fallback"

        search_info = {
            "query": query,
            "result_count": total_results,
            "strategy": strategy,
            "debug_info": {
                "segmented_query": seg_list,
                "text_results": len(text_search_results),
                "multi_keyword_results": len(multi_keyword_results),
                "single_keyword_results": len(single_keyword_results),
                "title_results": len(title_search_results),
                "keyword_array_results": len(keyword_array_results)
            }
        }

        return {"articles": articles, "pagination": pagination, "search_info": search_info}

# 创建改进版服务实例
civil_code_service_improved = CivilCodeServiceImproved()
